# -*- coding:utf-8 -*-
import os
import sys
import maya.cmds as cmds
import json
import maya.OpenMayaUI as apiUI
from shiboken2 import wrapInstance
from PySide2.QtGui import *
from PySide2.QtCore import *
from PySide2.QtWidgets import *



def maya_main_window():

    main_win_ptr = apiUI.MQtUtil.mainWindow()
    return wrapInstance(long(main_win_ptr), QWidget)



class TDialog(QDialog):

    def __init__(self):
        super(TDialog, self).__init__()

        self.setWindowTitle(u'abc材质导入导出')
        self.main_layout = QHBoxLayout()
        self.main_layout.setAlignment(Qt.AlignTop)
        self.main_layout.setSpacing(20)
        self.left_layout = QVBoxLayout()
        self.export_label = QLabel(u'导出所选择物体材质信息')
        self.export_label.setAlignment(Qt.AlignCenter)
        self.export_layout = QHBoxLayout()
        self.path_label = QLabel(u'导出目录:')
        self.path_eidt = QLineEdit()
        self.path_btn = QPushButton(u'选择')
        self.path_btn.clicked.connect(self._chooseDir)
        self.info_layout = QHBoxLayout()
        self.info_label = QLabel(u'文件名称:')
        self.info_eidt = QLineEdit()
        self.force_check = QCheckBox(u'强制导出（保证已有的有缺失的让他缺失）')
        self.export_btn = QPushButton(u'导出')
        self.export_btn.clicked.connect(self._export_matInfo)
        self.export_btn.setMinimumHeight(50)
        self.info_layout.addWidget(self.info_label)
        self.info_layout.addWidget(self.info_eidt)
        self.export_layout.addWidget(self.path_label)
        self.export_layout.addWidget(self.path_eidt)
        self.export_layout.addWidget(self.path_btn)
        self.left_layout.addWidget(self.export_label)
        self.left_layout.addLayout(self.export_layout)
        self.left_layout.addLayout(self.info_layout)
        self.left_layout.addWidget(self.force_check)
        self.left_layout.addWidget(self.export_btn)

        self.right_layout = QVBoxLayout()
        self.right_layout.setContentsMargins(60,0,0,0)
        self.import_label = QLabel(u'导入材质信息')
        self.import_label.setAlignment(Qt.AlignCenter)
        self.matinfo_layout = QHBoxLayout()
        self.matinfo_label = QLabel(u'材质信息路径:')
        self.matinfo_edit = QLineEdit()
        self.matinfo_btn = QPushButton(u'选择')
        self.matinfo_btn.clicked.connect(self._chooseFile)
        self.matinfo_layout.addWidget(self.matinfo_label)
        self.matinfo_layout.addWidget(self.matinfo_edit)
        self.matinfo_layout.addWidget(self.matinfo_btn)
        self.import_btn = QPushButton(u'对选择abc添加材质')
        self.import_btn.clicked.connect(self._import_mat)
        self.import_btn.setMinimumHeight(50)
        self.right_layout.addWidget(self.import_label)
        self.right_layout.addLayout(self.matinfo_layout)
        self.right_layout.addWidget(self.import_btn)

        self.main_layout.addLayout(self.left_layout)
        self.main_layout.addLayout(self.right_layout)
        self.setLayout(self.main_layout)

    def get_filetype(self):
        ft = cmds.file(q=True,sn=True)
        if ft.endswith('ma'):
            return 'mayaAscii','.ma'
        else:
            return 'mayaBinary','.mb'

    def _chooseDir(self):
        _dir = QFileDialog.getExistingDirectory(self,u'选择目录')
        self.path_eidt.setText(_dir)

    def _chooseFile(self):
        fileName = QFileDialog.getOpenFileName(self,u'选择文件',u'*matInfo')
        self.matinfo_edit.setText(fileName[0])

    def _saveMa(self,path,tp):
        cmds.select(clear=True)
        sall = cmds.ls(geometry=True,lights=True,typ='transform')
        cmds.select(sall)
        cmds.delete()
        cmds.file(rename=path)
        cmds.file(save=True, typ=tp)
        # z = cmds.ls(mat=1)
        # cmds.select(z)
        # cmds.file(path, force=True, typ=tp, exportSelected=True, preserveReferences=True,
        #           shader=True, expressions=True, constructionHistory=True)

    def _export_matInfo(self):
        result = QMessageBox.question(self, u'提示', u'此操作会保存文件，然后清空场景输出一份材质文件，是否保存并输出', QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
        if result == QMessageBox.Yes:
            currentPath = cmds.file()
            tp, ext = self.get_filetype()
            cmds.file(save=True, typ=tp)#currentPath,
            path = self.path_eidt.text()
            name = self.info_eidt.text()
            export_path = os.path.join(path, name)

            ma_path = os.path.join(path, name + ext)
            back = self.writeJson(export_path)
            if back:
                self._saveMa(ma_path, tp)
                QMessageBox.information(self, u'提示', u'导出成功')
            else:
                QMessageBox.information(self, u'提示', u'导出失败')
        else:
            print('No')

    def getAiAttr(self,n):
        """
        传入选择的物体名称，这里是几何体名称，不能是shape名称
        :param n:
        :return:
        """
        aiAttrDic = {}
        shape = cmds.listRelatives(n)[0]

        #Arnold
        aiTranslator = cmds.getAttr(shape + '.aiTranslator')
        aiOpaque = cmds.getAttr(shape + '.aiOpaque')
        aiOpaque = 1 if aiOpaque else 0
        aiMatte = cmds.getAttr(shape + '.aiMatte')
        aiMatte = 1 if aiMatte else 0

        #mnesh_light
        colorValue = cmds.getAttr(shape + '.color')[0]  # list
        cmds.setAttr(shape + '.color', 1, 1, 1, type='double3')  # ,type='list'
        # cmds.setAttr(shape+'.aiTranslator','mesh_light',type='string')#
        intensity = cmds.getAttr(shape + '.intensity')
        aiExposure = cmds.getAttr(shape + '.aiExposure')
        aiUseColorTemperature = cmds.getAttr(shape + '.aiUseColorTemperature')
        aiUseColorTemperature = 1 if aiUseColorTemperature else 0
        aiColorTemperature = cmds.getAttr(shape + '.aiColorTemperature')
        aiSamples = cmds.getAttr(shape + '.aiSamples')
        aiVolumeSamples = cmds.getAttr(shape + '.aiVolumeSamples')
        lightVisible = cmds.getAttr(shape+'.lightVisible')
        lightVisible = 1 if lightVisible else 0

        #Subdivision
        aiSubdivType = cmds.getAttr(shape + '.aiSubdivType')
        aiSubdivIterations = cmds.getAttr(shape + '.aiSubdivIterations')
        aiSubdivAdaptiveMetric = cmds.getAttr(shape + '.aiSubdivAdaptiveMetric')
        aiSubdivPixelError = cmds.getAttr(shape + '.aiSubdivPixelError')
        aiSubdivAdaptiveSpace = cmds.getAttr(shape + '.aiSubdivAdaptiveSpace')
        aiSubdivUvSmoothing = cmds.getAttr(shape + '.aiSubdivUvSmoothing')
        aiSubdivSmoothDerivs = cmds.getAttr(shape + '.aiSubdivSmoothDerivs')
        aiSubdivFrustumIgnore = cmds.getAttr(shape + '.aiSubdivFrustumIgnore')


        #Displacement Attributes
        aiDispHeight = cmds.getAttr(shape+'.aiDispHeight')
        aiDispPadding = cmds.getAttr(shape+'.aiDispPadding')
        aiDispZeroValue = cmds.getAttr(shape+'.aiDispZeroValue')

        aiAttrDic['aiTranslator'] = aiTranslator
        aiAttrDic['aiOpaque'] = aiOpaque
        aiAttrDic['aiMatte'] = aiMatte
        aiAttrDic['aiSubdivIterations'] = aiSubdivIterations
        aiAttrDic['color'] = colorValue
        aiAttrDic['intensity'] = intensity
        aiAttrDic['aiExposure'] = aiExposure
        aiAttrDic['aiUseColorTemperature'] = aiUseColorTemperature
        aiAttrDic['aiColorTemperature'] = aiColorTemperature
        aiAttrDic['aiSamples'] = aiSamples
        aiAttrDic['aiVolumeSamples'] = aiVolumeSamples
        aiAttrDic['lightVisible'] = lightVisible
        aiAttrDic['aiSubdivType'] = aiSubdivType
        aiAttrDic['aiSubdivAdaptiveMetric'] = aiSubdivAdaptiveMetric
        aiAttrDic['aiSubdivPixelError'] = aiSubdivPixelError
        aiAttrDic['aiSubdivAdaptiveSpace'] = aiSubdivAdaptiveSpace
        aiAttrDic['aiSubdivUvSmoothing'] = aiSubdivUvSmoothing
        aiAttrDic['aiSubdivSmoothDerivs'] = aiSubdivSmoothDerivs
        aiAttrDic['aiSubdivFrustumIgnore'] = aiSubdivFrustumIgnore

        aiAttrDic['aiDispHeight'] = aiDispHeight
        aiAttrDic['aiDispPadding'] = aiDispPadding
        aiAttrDic['aiDispZeroValue'] = aiDispZeroValue

        return aiAttrDic

    def _get_shader_name_type(self,sg):
        """
        传入该材质的sg节点，来过滤获取材质的名称
        :param sg:
        :return:
        """
        shader_name = ''
        shader_type = ''
        shader_type_list = ['lambert','blinn','aiStandardSurface','aiCarPaint','aiLayerShader','aiStandardHair','aiToon','aiStandardVolume']
        for i in shader_type_list:
            shader = cmds.listConnections(sg, type=i)
            if shader:
                shader_name = shader

        if shader_name:
            shader_type = cmds.nodeType(shader_name)

        return shader_name,shader_type

    def getSurfaceAttrDict(self,shaderName):
        """
        获取标准材质数值映射表
        :param shaderName:
        :return:
        """
        matAttr = {}
        # Base
        base = cmds.getAttr(shaderName + '.base')
        baseColor = cmds.getAttr(shaderName + '.baseColor')[0]
        diffuseRoughness = cmds.getAttr(shaderName + '.diffuseRoughness')
        metalness = cmds.getAttr(shaderName + '.metalness')
        matAttr['base'] = base
        matAttr['base_color'] = baseColor
        matAttr['base_colorr'] = baseColor[0]
        matAttr['base_colorg'] = baseColor[1]
        matAttr['base_colorb'] = baseColor[2]
        matAttr['diffuse_roughness'] = diffuseRoughness
        matAttr['metalness'] = metalness
        # Specular
        specular = cmds.getAttr(shaderName + '.specular')
        specularColor = cmds.getAttr(shaderName + '.specularColor')[0]
        specularRoughness = cmds.getAttr(shaderName + '.specularRoughness')
        specularIOR = cmds.getAttr(shaderName + '.specularIOR')
        specularAnisotropy = cmds.getAttr(shaderName + '.specularAnisotropy')
        specularRotation = cmds.getAttr(shaderName + '.specularRotation')
        matAttr['specular'] = specular
        matAttr['specular_color'] = specularColor
        matAttr['specular_colorr'] = specularColor[0]
        matAttr['specular_colorg'] = specularColor[1]
        matAttr['specular_colorb'] = specularColor[2]
        matAttr['specular_roughness'] = specularRoughness
        matAttr['specular_IOR'] = specularIOR
        matAttr['specular_anisotropy'] = specularAnisotropy
        matAttr['specular_rotation'] = specularRotation
        # Transmission
        transmission = cmds.getAttr(shaderName + '.transmission')
        transmissionColor = cmds.getAttr(shaderName + '.transmissionColor')[0]
        transmissionDepth = cmds.getAttr(shaderName + '.transmissionDepth')
        transmissionScatter = cmds.getAttr(shaderName + '.transmissionScatter')[0]
        transmissionScatterAnisotropy = cmds.getAttr(shaderName + '.transmissionScatterAnisotropy')
        transmissionDispersion = cmds.getAttr(shaderName + '.transmissionDispersion')
        transmissionExtraRoughness = cmds.getAttr(shaderName + '.transmissionExtraRoughness')
        matAttr['transmission'] = transmission
        matAttr['transmission_color'] = transmissionColor
        matAttr['transmission_colorr'] = transmissionColor[0]
        matAttr['transmission_colorg'] = transmissionColor[1]
        matAttr['transmission_colorb'] = transmissionColor[2]
        matAttr['transmission_depth'] = transmissionDepth
        matAttr['transmission_scatter'] = transmissionScatter
        matAttr['transmission_scatterr'] = transmissionScatter[0]
        matAttr['transmission_scatterg'] = transmissionScatter[1]
        matAttr['transmission_scatterb'] = transmissionScatter[2]
        matAttr['transmission_scatter_anisotropy'] = transmissionScatterAnisotropy
        matAttr['transmission_dispersion'] = transmissionDispersion
        matAttr['transmission_extra_roughness'] = transmissionExtraRoughness
        # subsurface
        subsurface = cmds.getAttr(shaderName + '.subsurface')
        subsurfaceColor = cmds.getAttr(shaderName + '.subsurfaceColor')[0]
        subsurfaceRadius = cmds.getAttr(shaderName + '.subsurfaceRadius')[0]
        subsurfaceScale = cmds.getAttr(shaderName + '.subsurfaceScale')
        subsurfaceTypeValue = cmds.getAttr(shaderName + '.subsurfaceType')  # 这里0 对应diffusion  1对应randomwalk
        subsurfaceType = 'diffusion' if subsurfaceTypeValue == 0 else 'randomwalk'
        subsurfaceAnisotropy = cmds.getAttr(shaderName + '.subsurfaceAnisotropy')
        matAttr['subsurface'] = subsurface
        matAttr['subsurface_color'] = subsurfaceColor
        matAttr['subsurface_colorr'] = subsurfaceColor[0]
        matAttr['subsurface_colorg'] = subsurfaceColor[1]
        matAttr['subsurface_colorb'] = subsurfaceColor[2]
        matAttr['subsurface_radius'] = subsurfaceRadius
        matAttr['subsurface_radiusr'] = subsurfaceRadius[0]
        matAttr['subsurface_radiusg'] = subsurfaceRadius[1]
        matAttr['subsurface_radiusb'] = subsurfaceRadius[2]
        matAttr['subsurface_scale'] = subsurfaceScale
        matAttr['subsurface_type'] = subsurfaceType
        matAttr['subsurface_anisotropy'] = subsurfaceAnisotropy
        # Coat
        coat = cmds.getAttr(shaderName + '.coat')
        coatColor = cmds.getAttr(shaderName + '.coatColor')[0]
        coatRoughness = cmds.getAttr(shaderName + '.coatRoughness')
        coatIOR = cmds.getAttr(shaderName + '.coatIOR')
        coatNormal = cmds.getAttr(shaderName + '.coatNormal')[0]
        matAttr['coat'] = coat
        matAttr['coat_color'] = coatColor
        matAttr['coat_colorr'] = coatColor[0]
        matAttr['coat_colorg'] = coatColor[1]
        matAttr['coat_colorb'] = coatColor[2]
        matAttr['coat_roughness'] = coatRoughness
        matAttr['coat_IOR'] = coatIOR
        matAttr['coat_normal'] = coatNormal
        matAttr['coat_normalx'] = coatNormal[0]
        matAttr['coat_normaly'] = coatNormal[1]
        matAttr['coat_normalz'] = coatNormal[2]
        # Sheen
        sheen = cmds.getAttr(shaderName + '.sheen')
        sheenColor = cmds.getAttr(shaderName + '.sheenColor')[0]
        sheenRoughness = cmds.getAttr(shaderName + '.sheenRoughness')
        matAttr['sheen'] = sheen
        matAttr['sheen_color'] = sheenColor
        matAttr['sheen_colorr'] = sheenColor[0]
        matAttr['sheen_colorg'] = sheenColor[1]
        matAttr['sheen_colorb'] = sheenColor[2]
        matAttr['sheen_roughness'] = sheenRoughness
        # Emission
        emission = cmds.getAttr(shaderName + '.emission')
        emissionColor = cmds.getAttr(shaderName + '.emissionColor')[0]
        matAttr['emission'] = emission
        matAttr['emission_color'] = emissionColor
        matAttr['emission_colorr'] = emissionColor[0]
        matAttr['emission_colorg'] = emissionColor[1]
        matAttr['emission_colorb'] = emissionColor[2]
        # Geometry
        opacity = cmds.getAttr(shaderName + '.opacity')[0]
        normalCamera = cmds.getAttr(shaderName + '.normalCamera')[0]
        tangent = cmds.getAttr(shaderName + '.tangent')[0]
        matAttr['opacity'] = opacity
        matAttr['opacityr'] = opacity[0]
        matAttr['opacityg'] = opacity[1]
        matAttr['opacityb'] = opacity[2]
        matAttr['normal'] = normalCamera
        matAttr['normalx'] = normalCamera[0]
        matAttr['normaly'] = normalCamera[1]
        matAttr['normalz'] = normalCamera[2]
        matAttr['tangent'] = tangent
        matAttr['tangentx'] = tangent[0]
        matAttr['tangenty'] = tangent[1]
        matAttr['tangentz'] = tangent[2]
        return matAttr

    def getCarAttrDict(self,shaderName):
        """
        获取车漆材质值映射
        :param shaderName:
        :return:
        """
        matAttr = {}
        # Base
        base = cmds.getAttr(shaderName + '.base')
        baseColor = cmds.getAttr(shaderName + '.baseColor')[0]
        baseRoughness = cmds.getAttr(shaderName + '.baseRoughness')
        matAttr['base'] = base
        matAttr['base_color'] = baseColor
        matAttr['base_colorr'] = baseColor[0]
        matAttr['base_colorg'] = baseColor[1]
        matAttr['base_colorb'] = baseColor[2]
        matAttr['base_roughness'] = baseRoughness
        # Specular
        specular = cmds.getAttr(shaderName + '.specular')
        specularColor = cmds.getAttr(shaderName + '.specularColor')[0]
        specularFlipFlop = cmds.getAttr(shaderName + '.specularFlipFlop')[0]
        specularLightFacing = cmds.getAttr(shaderName + '.specularLightFacing')[0]
        specularFalloff = cmds.getAttr(shaderName + '.specularFalloff')
        specularRoughness = cmds.getAttr(shaderName + '.specularRoughness')
        specularIOR = cmds.getAttr(shaderName + '.specularIOR')
        transmissionColor = cmds.getAttr(shaderName + '.transmissionColor')[0]
        matAttr['specular'] = specular
        matAttr['specular_color'] = specularColor
        matAttr['specular_colorr'] = specularColor[0]
        matAttr['specular_colorg'] = specularColor[1]
        matAttr['specular_colorb'] = specularColor[2]
        matAttr['specular_flip_flop'] = specularFlipFlop
        matAttr['specular_flip_flopr'] = specularFlipFlop[0]
        matAttr['specular_flip_flopg'] = specularFlipFlop[1]
        matAttr['specular_flip_flopb'] = specularFlipFlop[2]
        matAttr['specular_light_facing'] = specularLightFacing
        matAttr['specular_light_facingr'] = specularLightFacing[0]
        matAttr['specular_light_facingg'] = specularLightFacing[1]
        matAttr['specular_light_facingb'] = specularLightFacing[2]
        matAttr['specular_falloff'] = specularFalloff
        matAttr['specular_roughness'] = specularRoughness
        matAttr['specular_IOR'] = specularIOR
        matAttr['transmission_color'] = transmissionColor
        matAttr['transmission_colorr'] = transmissionColor[0]
        matAttr['transmission_colorg'] = transmissionColor[1]
        matAttr['transmission_colorb'] = transmissionColor[2]
        # Flakes
        flakeColor = cmds.getAttr(shaderName + '.flakeColor')[0]
        flakeFlipFlop = cmds.getAttr(shaderName + '.flakeFlipFlop')[0]
        flakeLightFacing = cmds.getAttr(shaderName + '.flakeLightFacing')[0]
        flakeFalloff = cmds.getAttr(shaderName + '.flakeFalloff')
        flakeRoughness = cmds.getAttr(shaderName + '.flakeRoughness')
        flakeIOR = cmds.getAttr(shaderName + '.flakeIOR')
        flakeScale = cmds.getAttr(shaderName + '.flakeScale')
        flakeDensity = cmds.getAttr(shaderName + '.flakeDensity')
        flakeLayers = cmds.getAttr(shaderName + '.flakeLayers')
        flakeNormalRandomize = cmds.getAttr(shaderName + '.flakeNormalRandomize')
        flakeCoordSpaceList = ['world', 'object', 'pref', 'uv']
        flakeCoordSpaceIndex = cmds.getAttr(shaderName + '.flakeCoordSpace')
        flakeCoordSpace = flakeCoordSpaceList[flakeCoordSpaceIndex]
        matAttr['flake_color'] = flakeColor
        matAttr['flake_colorr'] = flakeColor[0]
        matAttr['flake_colorg'] = flakeColor[1]
        matAttr['flake_colorb'] = flakeColor[2]
        matAttr['flake_flip_flop'] = flakeFlipFlop
        matAttr['flake_flip_flopr'] = flakeFlipFlop[0]
        matAttr['flake_flip_flopg'] = flakeFlipFlop[1]
        matAttr['flake_flip_flopb'] = flakeFlipFlop[2]
        matAttr['flake_light_facing'] = flakeLightFacing
        matAttr['flake_light_facingr'] = flakeLightFacing[0]
        matAttr['flake_light_facingg'] = flakeLightFacing[1]
        matAttr['flake_light_facingb'] = flakeLightFacing[2]
        matAttr['flake_falloff'] = flakeFalloff
        matAttr['flake_roughness'] = flakeRoughness
        matAttr['flake_IOR'] = flakeIOR
        matAttr['flake_scale'] = flakeScale
        matAttr['flake_density'] = flakeDensity
        matAttr['flake_layers'] = flakeLayers
        matAttr['flake_normal_randomize'] = flakeNormalRandomize
        matAttr['flake_coord_space'] = flakeCoordSpace
        # Coat
        coat = cmds.getAttr(shaderName + '.coat')
        coatColor = cmds.getAttr(shaderName + '.coatColor')[0]
        coatRoughness = cmds.getAttr(shaderName + '.coatRoughness')
        coatIOR = cmds.getAttr(shaderName + '.coatIOR')
        flakeRoughness = cmds.getAttr(shaderName + '.flakeRoughness')
        coatNormal = cmds.getAttr(shaderName + '.coatNormal')[0]
        matAttr['coat'] = coat
        matAttr['coat_color'] = coatColor
        matAttr['coat_colorr'] = coatColor[0]
        matAttr['coat_colorg'] = coatColor[1]
        matAttr['coat_colorb'] = coatColor[2]
        matAttr['coat_roughness'] = coatRoughness
        matAttr['coat_IOR'] = coatIOR
        matAttr['flake_roughness'] = flakeRoughness
        matAttr['coat_normal'] = coatNormal
        matAttr['coat_normalx'] = coatNormal[0]
        matAttr['coat_normaly'] = coatNormal[1]
        matAttr['coat_normalz'] = coatNormal[2]
        return matAttr

    def getHairAttrDict(self,shaderName):
        """
        获取毛发材质值映射
        :param shaderName:
        :return:
        """

        matAttr = {}
        # Color
        base = cmds.getAttr(shaderName + '.base')
        baseColor = cmds.getAttr(shaderName + '.baseColor')[0]
        melanin = cmds.getAttr(shaderName + '.melanin')
        melaninRedness = cmds.getAttr(shaderName + '.melaninRedness')
        melaninRandomize = cmds.getAttr(shaderName + '.melaninRandomize')
        matAttr['base'] = base
        matAttr['base_color'] = baseColor
        matAttr['base_colorr'] = baseColor[0]
        matAttr['base_colorg'] = baseColor[1]
        matAttr['base_colorb'] = baseColor[2]
        matAttr['melanin'] = melanin
        matAttr['melanin_redness'] = melaninRedness
        matAttr['melanin_randomize'] = melaninRandomize

        # Specular
        roughness = cmds.getAttr(shaderName + '.roughness')
        ior = cmds.getAttr(shaderName + '.ior')
        shift = cmds.getAttr(shaderName + '.shift')
        matAttr['roughness'] = roughness
        matAttr['ior'] = ior
        matAttr['shift'] = shift
        # Tint
        specularTint = cmds.getAttr(shaderName + '.specularTint')[0]
        specular2Tint = cmds.getAttr(shaderName + '.specular2Tint')[0]
        transmissionTint = cmds.getAttr(shaderName + '.transmissionTint')[0]
        matAttr['specular_tint'] = specularTint
        matAttr['specular_tintr'] = specularTint[0]
        matAttr['specular_tintg'] = specularTint[1]
        matAttr['specular_tintb'] = specularTint[2]
        matAttr['specular2_tint'] = specular2Tint
        matAttr['specular2_tintr'] = specular2Tint[0]
        matAttr['specular2_tintg'] = specular2Tint[1]
        matAttr['specular2_tintb'] = specular2Tint[2]
        matAttr['transmission_tint'] = transmissionTint
        matAttr['transmission_tintr'] = transmissionTint[0]
        matAttr['transmission_tintg'] = transmissionTint[1]
        matAttr['transmission_tintb'] = transmissionTint[2]
        # Diffuse
        diffuse = cmds.getAttr(shaderName + '.diffuse')
        diffuseColor = cmds.getAttr(shaderName + '.diffuseColor')[0]
        matAttr['diffuse'] = diffuse
        matAttr['diffuse_color'] = diffuseColor
        matAttr['diffuse_colorr'] = diffuseColor[0]
        matAttr['diffuse_colorg'] = diffuseColor[1]
        matAttr['diffuse_colorb'] = diffuseColor[2]
        # Emission
        emission = cmds.getAttr(shaderName + '.emission')
        emissionColor = cmds.getAttr(shaderName + '.emissionColor')[0]
        opacity = cmds.getAttr(shaderName + '.opacity')[0]
        matAttr['emission'] = emission
        matAttr['emission_color'] = emissionColor
        matAttr['emission_colorr'] = emissionColor[0]
        matAttr['emission_colorg'] = emissionColor[1]
        matAttr['emission_colorb'] = emissionColor[2]
        matAttr['opacity'] = opacity
        matAttr['opacityr'] = opacity[0]
        matAttr['opacityg'] = opacity[1]
        matAttr['opacityb'] = opacity[2]
        return matAttr

    def getToonAttrDict(self,shaderName):
        """
        获取卡通材质值映射
        :param shaderName:
        :return:
        """
        matAttr = {}
        # Edge
        enable = cmds.getAttr(shaderName + '.enable')
        edgeColor = cmds.getAttr(shaderName + '.edgeColor')[0]
        edgeTonemap = cmds.getAttr(shaderName + '.edgeTonemap')[0]
        edgeOpacity = cmds.getAttr(shaderName + '.edgeOpacity')
        edgeWidthScale = cmds.getAttr(shaderName + '.edgeWidthScale')
        matAttr['enable'] = enable
        matAttr['edge_color'] = edgeColor
        matAttr['edge_colorr'] = edgeColor[0]
        matAttr['edge_colorg'] = edgeColor[1]
        matAttr['edge_colorb'] = edgeColor[2]
        matAttr['edge_tonemap'] = edgeTonemap
        matAttr['edge_tonemapr'] = edgeTonemap[0]
        matAttr['edge_tonemapg'] = edgeTonemap[1]
        matAttr['edge_tonemapb'] = edgeTonemap[2]
        matAttr['edge_opacity'] = edgeOpacity
        matAttr['edge_width_scale'] = edgeWidthScale

        # Edge Detection  在houdini里这个属于Edge
        idDifference = cmds.getAttr(shaderName + '.idDifference')
        shaderDifference = cmds.getAttr(shaderName + '.shaderDifference')
        maskColor = cmds.getAttr(shaderName + '.maskColor')[0]
        uvThreshold = cmds.getAttr(shaderName + '.uvThreshold')
        angleThreshold = cmds.getAttr(shaderName + '.angleThreshold')
        normalTypeList = ['shading normal', 'smoothed normal', 'geometric normal']
        normalTypeIndex = cmds.getAttr(shaderName + '.normalType')
        normalType = normalTypeList[normalTypeIndex]
        matAttr['idDifference'] = idDifference
        matAttr['shader_difference'] = shaderDifference
        matAttr['mask_color'] = maskColor
        matAttr['mask_colorr'] = maskColor[0]
        matAttr['mask_colorg'] = maskColor[1]
        matAttr['mask_colorb'] = maskColor[2]
        matAttr['uv_threshold'] = uvThreshold
        matAttr['angle_threshold'] = angleThreshold
        matAttr['normalType'] = normalType

        # Adavanced Edge Control 在houdini里这个也属于Edge
        priority = cmds.getAttr(shaderName + '.priority')
        ignoreThroughput = cmds.getAttr(shaderName + '.ignoreThroughput')
        userId = cmds.getAttr(shaderName + '.userId')
        matAttr['priority'] = priority
        matAttr['ignore_throughput'] = ignoreThroughput
        matAttr['user_id'] = userId

        # Silhouette
        enableSilhouette = cmds.getAttr(shaderName + '.enableSilhouette')
        silhouetteColor = cmds.getAttr(shaderName + '.silhouetteColor')[0]
        silhouetteOpacity = cmds.getAttr(shaderName + '.silhouetteOpacity')
        silhouetteWidthScale = cmds.getAttr(shaderName + '.silhouetteWidthScale')
        matAttr['enable_silhouette'] = enableSilhouette
        matAttr['silhouette_color'] = silhouetteColor
        matAttr['silhouette_colorr'] = silhouetteColor[0]
        matAttr['silhouette_colorg'] = silhouetteColor[1]
        matAttr['silhouette_colorb'] = silhouetteColor[2]
        matAttr['silhouette_opacity'] = silhouetteOpacity
        matAttr['silhouette_widthScale'] = silhouetteWidthScale

        # Base
        base = cmds.getAttr(shaderName + '.base')
        baseColor = cmds.getAttr(shaderName + '.baseColor')[0]
        baseTonemap = cmds.getAttr(shaderName + '.baseTonemap')[0]
        matAttr['enable_silhouette'] = base
        matAttr['base_color'] = baseColor
        matAttr['base_colorr'] = baseColor[0]
        matAttr['base_colorg'] = baseColor[1]
        matAttr['base_colorb'] = baseColor[2]
        matAttr['base_tonemap'] = baseTonemap
        matAttr['base_tonemapr'] = baseTonemap[0]
        matAttr['base_tonemapg'] = baseTonemap[1]
        matAttr['base_tonemapb'] = baseTonemap[2]
        # Specular
        specular = cmds.getAttr(shaderName + '.specular')
        specularColor = cmds.getAttr(shaderName + '.specularColor')[0]
        specularRoughness = cmds.getAttr(shaderName + '.specularRoughness')
        specularAnisotropy = cmds.getAttr(shaderName + '.specularAnisotropy')
        specularRotation = cmds.getAttr(shaderName + '.specularRotation')
        specularTonemap = cmds.getAttr(shaderName + '.specularTonemap')[0]
        matAttr['specular'] = specular
        matAttr['specular_color'] = specularColor
        matAttr['specular_colorr'] = specularColor[0]
        matAttr['specular_colorg'] = specularColor[1]
        matAttr['specular_colorb'] = specularColor[2]
        matAttr['specular_roughness'] = specularRoughness
        matAttr['specular_anisotropy'] = specularAnisotropy
        matAttr['specular_rotation'] = specularRotation
        matAttr['specular_tonemap'] = specularTonemap
        matAttr['specular_tonemapr'] = specularTonemap[0]
        matAttr['specular_tonemapg'] = specularTonemap[1]
        matAttr['specular_tonemapb'] = specularTonemap[2]
        # Stylized Highlight
        lights = cmds.getAttr(shaderName + '.lights')
        highlightColor = cmds.getAttr(shaderName + '.highlightColor')[0]
        highlightSize = cmds.getAttr(shaderName + '.highlightSize')
        matAttr['lights'] = lights
        matAttr['highlight_color'] = highlightColor
        matAttr['highlight_colorr'] = highlightColor[0]
        matAttr['highlight_colorg'] = highlightColor[1]
        matAttr['highlight_colorb'] = highlightColor[2]
        matAttr['highlight_size'] = highlightSize

        # Rim Lighting
        rimLight = cmds.getAttr(shaderName + '.rimLight')
        rimLightColor = cmds.getAttr(shaderName + '.rimLightColor')[0]
        rimLightWidth = cmds.getAttr(shaderName + '.rimLightWidth')
        matAttr['rimLight'] = rimLight
        matAttr['rimLight_color'] = rimLightColor
        matAttr['rimLight_colorr'] = rimLightColor[0]
        matAttr['rimLight_colorg'] = rimLightColor[1]
        matAttr['rimLight_colorb'] = rimLightColor[2]
        matAttr['rimLight_width'] = rimLightWidth

        # Transmission
        transmission = cmds.getAttr(shaderName + '.transmission')
        transmissionColor = cmds.getAttr(shaderName + '.transmissionColor')[0]
        transmissionRoughness = cmds.getAttr(shaderName + '.transmissionRoughness')
        transmissionAnisotropy = cmds.getAttr(shaderName + '.transmissionAnisotropy')
        transmissionRotation = cmds.getAttr(shaderName + '.transmissionRotation')
        IOR = cmds.getAttr(shaderName + '.IOR')
        matAttr['transmission'] = transmission
        matAttr['transmission_color'] = transmissionColor
        matAttr['transmission_colorr'] = transmissionColor[0]
        matAttr['transmission_colorg'] = transmissionColor[1]
        matAttr['transmission_colorb'] = transmissionColor[2]
        matAttr['transmission_roughness'] = transmissionRoughness
        matAttr['transmission_anisotropy'] = transmissionAnisotropy
        matAttr['transmission_rotation'] = transmissionRotation
        matAttr['IOR'] = IOR

        # Sheen 这个sheen类在houdini材质里有，maya在额外属性栏
        sheen = cmds.getAttr(shaderName + '.sheen')
        sheenColor = cmds.getAttr(shaderName + '.sheenColor')[0]
        sheenRoughness = cmds.getAttr(shaderName + '.sheenRoughness')
        matAttr['sheen'] = sheen
        matAttr['sheen_color'] = sheenColor
        matAttr['sheen_colorr'] = sheenColor[0]
        matAttr['sheen_colorg'] = sheenColor[1]
        matAttr['sheen_colorb'] = sheenColor[2]
        matAttr['sheen_roughness'] = sheenRoughness

        # Emission
        emission = cmds.getAttr(shaderName + '.emission')
        emissionColor = cmds.getAttr(shaderName + '.emissionColor')[0]
        matAttr['emission'] = emission
        matAttr['emission_color'] = emissionColor
        matAttr['emission_colorr'] = emissionColor[0]
        matAttr['emission_colorg'] = emissionColor[1]
        matAttr['emission_colorb'] = emissionColor[2]
        # Geometry
        normalCamera = cmds.getAttr(shaderName + '.normalCamera')[0]
        tangent = cmds.getAttr(shaderName + '.tangent')[0]
        matAttr['normal'] = normalCamera  # houdini里计算normal
        matAttr['normalx'] = normalCamera[0]
        matAttr['normaly'] = normalCamera[1]
        matAttr['normalz'] = normalCamera[2]
        matAttr['tangent'] = tangent
        matAttr['tangentx'] = tangent[0]
        matAttr['tangenty'] = tangent[1]
        matAttr['tangentz'] = tangent[2]
        return matAttr

    def _get_attr(self,shader_type,shaderName):
        """
        根据节点类型与名称获取对应的参数映射值,
        这四种材质
        :param shader_type:现阶段就只读 aiStandardSurface，aiStandardHair，aiCarPaint,aiToon
        :return:
        """
        attr = {}
        if shader_type == 'aiStandardSurface':
            attr = self.getSurfaceAttrDict(shaderName)
        elif shader_type == 'aiStandardHair':
            attr = self.getHairAttrDict(shaderName)
        elif shader_type == 'aiCarPaint':
            attr = self.getCarAttrDict(shaderName)
        elif shader_type == 'aiToon':
            attr = shader_type.getToonAttrDict(shaderName)

        return attr


    def camelToSnake(self,s):
        up_index = []
        for i, c in enumerate(s):
            if c.isupper():
                up_index.append(i)
        ls = s.lower()
        # print(ls)
        list_ls = list(ls)
        if up_index:
            addi = 0
            for g in up_index:
                list_ls.insert(g + addi, '_')
                addi += 1
        last_ls = ''.join(list_ls)
        # print(last_ls)
        return last_ls

    def _get_shader_parms_path(self,shader_name,parms_list):
        """
        通过材质名称以及传入的材质参数列表，去循环读取对于的路径。
        :param shader_name:
        :param parms_list: 需要根据材质类型来对应传入
        :return:
        """
        path_dic={}
        for p in parms_list:
            parname = shader_name + '.' + p
            if cmds.listConnections(parname):
                filenode = cmds.listConnections(parname)[0]
                sp = self.camelToSnake(p)
                try:
                    filenode = cmds.listConnections(filenode, type='file')[0]
                except Exception as no_filenode_err:
                    pass
                path_dic[sp] = cmds.getAttr(filenode + '.fileTextureName')
        return path_dic


    def getMatInfo(self):
        # 统一UV象限 mel:polyCopyUV -uvSetNameInput "UVChannel_1" -uvSetName "map1"  -ch 1 pasted__pasted__pasted__pasted__polySurface15;
        #统一UV象限 cmds.polyCopyUV( 'pasted__pasted__pasted__pasted__polySurface15', uvi='UVChannel_1', uvs='map1' )
        #先将SG节点全都根据其所连的材质名称进行命名
        sgs = cmds.ls(typ='shadingEngine')
        for i in sgs:
            if i not in ['initialParticleSE', 'initialShadingGroup']:
                s = cmds.listConnections(i)
                mats = cmds.ls(s, materials=True)
                if mats:
                    mat = mats[0]
                    cmds.rename(i, mat + 'SG')

        sn = cmds.ls(sl=True)
        wrong_list = []  #错误的几何体名称
        poly_matDic = {}   #几何体与材质映射字典
        ai_attrDic = {}   #几何体maya中Arnold材质属性字典
        matList = []    #
        ArnoldmatPar = ['baseColor', 'specularColor', 'specularRoughness', 'opacity','normalCamera']  # ['color','KsColor','specularRoughness','opacity','normalCamera']#
        surface_par_list = ['base','baseColor', 'diffuseRoughness','metalness',
                          'specular','specularColor', 'specularRoughness','specularIOR','specularAnisotropy','specularRotation',
                          'transmission','transmissionColor','transmissionDepth','transmissionScatter','transmissionScatterAnisotropy','transmissionDispersion','transmissionExtraRoughness',
                          'subsurface','subsurfaceColor','subsurfaceRadius','subsurfaceScale','subsurfaceType','subsurfaceAnisotropy',
                          'coat','coatColor','coatRoughness','coatIOR','coatNormal',
                          'sheen','sheenColor','sheenRoughness',
                          'emission','emissionColor',
                          'opacity','normalCamera','tangent']
        hair_par_list = ['base','baseColor','melanin','melaninRedness','melaninRandomize',
                       'roughness','ior','shift',
                       'specularTint','specular2Tint','transmissionTint',
                       'diffuse','diffuseColor',
                       'emission','emissionColor','opacity']
        car_par_list = ['base','baseColor','baseRoughness',
                      'specular','specularColor','specularFlipFlop','specularLightFacing','specularFalloff','specularRoughness','specularIOR','transmissionColor',
                      'flakeColor','flakeFlipFlop','flakeLightFacing','flakeFalloff','flakeRoughness','flakeIOR','flakeScale','flakeDensity','flakeLayers','flakeNormalRandomize','flakeCoordSpace',
                      'coat','coatColor','coatRoughness','coatIOR','flakeRoughness','coatNormal']
        toon_par_list = ['enable','edgeColor','edgeTonemap','edgeOpacity','edgeWidthScale',
                       'idDifference','shaderDifference','maskColor','uvThreshold','angleThreshold','normalType',
                       'priority','ignoreThroughput','userId',
                       'enableSilhouette','silhouetteColor','silhouetteOpacity','silhouetteWidthScale',
                       'base','baseColor','baseTonemap',
                       'specular','specularColor','specularRoughness','specularAnisotropy','specularRotation','specularTonemap',
                       'lights','highlightColor','highlightSize',
                       'rimLight','rimLightColor','rimLightWidth',
                       'transmission','transmissionColor','transmissionRoughness','transmissionAnisotropy','transmissionRotation','IOR',
                       'sheen','sheenColor','sheenRoughness',
                       'emission','emissionColor',
                       'normalCamera','tangent']

        shader_par_map = {'aiStandardSurface':surface_par_list,'aiStandardHair':hair_par_list,'aiCarPaint':car_par_list,'aiToon':toon_par_list}


        print('here')
        for n in sn:
            try:
                getSG = cmds.listConnections(cmds.listRelatives(n), type='shadingEngine')[0]  #
                aiAttr = self.getAiAttr(n)
                ai_attrDic[n] = aiAttr
                shader_name,shader_type = self._get_shader_name_type(getSG)
                arnoldname = shader_name[0]
                #print(arnoldname)
                poly_matDic[n] = arnoldname
                matList.append(arnoldname)
            except Exception as get_s:
                print('***Error***:',str(n))
                print(str(get_s))
                wrong_list.append(n)

        AllMatList = list(set(matList))  #去重
        print(poly_matDic)
        print(AllMatList)

        mat_pathDic = {}
        try:
            for m in AllMatList:
                data = {}  #该材质的所有需要记录的信息 {"shader_type":"aiCarPaint","attr":{"base_color":[0.94,0.94,0.95],"melanin_redness":0.5,..},"path":{"opacity":"R://FNDH/Asset_work/xx/a.jpg","base_color":"R:..."}
                path_dic = {}  #该材质所有带贴图的属性以及贴图路径
                shader_type = cmds.nodeType(m)  #获取该shader的类型
                data['shader_type']=shader_type
                attr = self._get_attr(shader_type,m) #该材质球上的所有数值信息
                data['attr']=attr
                par_list = shader_par_map[shader_type]
                path_dic = self._get_shader_parms_path(m,par_list)

                #单独获取displacementShader的置换图路径
                getSG = cmds.listConnections(m, type='shadingEngine')[0]  #
                sg_displace = getSG + '.displacementShader'
                #print(sgName)
                if cmds.listConnections(sg_displace): #尝试获取置换连接
                    dispShader = cmds.listConnections(sg_displace)[0]
                    dispath = cmds.listConnections(dispShader, type='file')[0]
                    path_dic['displacementShader'] = cmds.getAttr(dispath + '.fileTextureName')
                    # if cmds.listConnections(parname):
                    #     if p == 'baseColor':
                    #         baseColor = cmds.listConnections(parname)[0]
                    #         path_dic['baseColor'] = cmds.getAttr(baseColor + '.fileTextureName')
                    #     elif p == 'specularColor':
                    #         specularColor = cmds.listConnections(parname)[0]
                    #         path_dic['specularColor'] = cmds.getAttr(specularColor + '.fileTextureName')
                    #     elif p == 'specularRoughness':
                    #         specularRoughness = cmds.listConnections(parname)[0]
                    #         path_dic['specularRoughness'] = cmds.getAttr(specularRoughness + '.fileTextureName')
                    #     elif p == 'opacity':
                    #         opacity = cmds.listConnections(parname)[0]
                    #         path_dic['opacity'] = cmds.getAttr(opacity + '.fileTextureName')
                    #     if p == 'normalCamera':
                    #         # par_vDic={}
                    #         bump = cmds.listConnections(parname)[0]
                    #         opacity = cmds.listConnections(bump, type='file')[0]
                    #         path_dic['bump'] = cmds.getAttr(opacity + '.fileTextureName')
                    #     else:
                    #         pass
                    # else:
                    #     pass
                data['path'] = path_dic
                mat_pathDic[m] = data
        except Exception as mat_ERR:
            print('***MatError***：',m)
            print(str(mat_ERR))
            # pass
        print('mat_pathDic:')
        print(mat_pathDic)

        mat_Info = {}
        mat_Info['poly_matDic'] = poly_matDic
        mat_Info['AllMatList'] = AllMatList
        mat_Info['mat_pathDic'] = mat_pathDic
        mat_Info['ai_attrDic'] = ai_attrDic

        print('mat_Info:')
        print(mat_Info)
        if self.force_check.isChecked():
            return mat_Info
        else:
            return mat_Info if not wrong_list else None


    def writeJson(self,path):

        jsonPath = path+ '.matInfo'
        jsonfile = open(jsonPath, 'w')
        data = self.getMatInfo()
        # print(data)
        if data:
            json.dump(data, jsonfile, ensure_ascii=False)
            # cmds.confirmDialog(title='?á??', message='?ê??', button=['?·??'])
            jsonfile.close()
            return 1
        else:
            return 0

    def setAiAttr(self,n,attrData):
        """
        设置物体Arnold属性面板参数
        :param n:
        :param attrData: {'aiTranslator':xxx,...}
        :return:
        """
        shape = cmds.listRelatives(n)[0]
        cmds.setAttr(shape + '.aiTranslator',attrData['aiTranslator'],type='string')
        cmds.setAttr(shape + '.aiOpaque',attrData['aiOpaque'])
        cmds.setAttr(shape + '.aiMatte',attrData['aiMatte'])
        cmds.setAttr(shape + '.aiSubdivIterations',attrData['aiSubdivIterations'])
        cmds.setAttr(shape + '.color', attrData['color'][0], attrData['color'][1], attrData['color'][2], type='double3')  # ,type='list'
        cmds.setAttr(shape + '.intensity',attrData['intensity'])
        cmds.setAttr(shape + '.aiExposure',attrData['aiExposure'])
        cmds.setAttr(shape + '.aiUseColorTemperature',attrData['aiUseColorTemperature'])
        cmds.setAttr(shape + '.aiColorTemperature',attrData['aiColorTemperature'])
        cmds.setAttr(shape + '.aiSamples',attrData['aiSamples'])
        cmds.setAttr(shape + '.aiVolumeSamples',attrData['aiVolumeSamples'])
        cmds.setAttr(shape + '.lightVisible',attrData['lightVisible'])
        cmds.setAttr(shape + '.aiSubdivType',attrData['aiSubdivType'])
        cmds.setAttr(shape + '.aiSubdivAdaptiveMetric',attrData['aiSubdivAdaptiveMetric'])
        cmds.setAttr(shape + '.aiSubdivPixelError',attrData['aiSubdivPixelError'])
        cmds.setAttr(shape + '.aiSubdivAdaptiveSpace',attrData['aiSubdivAdaptiveSpace'])
        cmds.setAttr(shape + '.aiSubdivUvSmoothing',attrData['aiSubdivUvSmoothing'])
        cmds.setAttr(shape + '.aiSubdivFrustumIgnore',attrData['aiSubdivFrustumIgnore'])
        cmds.setAttr(shape + '.aiDispHeight',attrData['aiDispHeight'])
        cmds.setAttr(shape + '.aiDispPadding',attrData['aiDispPadding'])
        cmds.setAttr(shape + '.aiDispZeroValue',attrData['aiDispZeroValue'])


    def _import_mat(self):
        info_path = self.matinfo_edit.text()
        info = {}
        if info_path:
            with open(info_path,'r') as r:
                # info = eval(r.read())
                info = json.loads(r.read())
        if info:
            wrone_label = False
            poly_matDic = info['poly_matDic']
            ai_attrDic = info['ai_attrDic']
            # print(poly_matDic)
            allmesh = cmds.ls(type='mesh')
            allpoly = cmds.listRelatives(allmesh,allParents=True)
            for i in allpoly:
                if i in poly_matDic.keys():
                    mat = poly_matDic[i]
                    sg = mat+'SG'
                    # sg=cmds.sets(empty=True,renderable=True,name=mat+'SG')
                    # cmds.connectAttr(mat+'.outColor',sg+'.surfaceShader',f=True)
                    attrData = ai_attrDic[i]
                    self.setAiAttr(i, attrData)
                    if mat!='lambert1':
                        try:
                            cmds.sets(i,e=1,forceElement=sg)
                            # cmds.polyCopyUV(i, uvi='UVChannel_1', uvs='map1')#copy uv sets
                        except Exception as ww:
                            wrone_label = True
                            print('erro_polyname:',i)
            if wrone_label == False:
                QMessageBox.information(None,u'提示',u'材质载入完成')
            else:
                QMessageBox.information(None, u'提示', u'材质载入失败')



if __name__ == '__main__':
    try:
        t.deleteLater()
    except:
        pass
    t = TDialog()
    try:
        t.create()
        t.show()
    except:
        t.deleteLater()
